#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>

#define _BSD_SOURCE


int number_of_channels = 5;
double signal_frequency = 100; //Hz 

int interval_between_exercises = 800; //ms


int how_often_max = 6;


int e1[] = {1980,2039,2111,2152,2213,2319,2260,2101,2150,2270,2334,2381,2410,2390,2377,2355,2442,2545,2486,2372,2321,2367,2405,2453,2516,2593,2693,2830,3006,3161,3248,3287,3296,3309,3353,3376,3361,3356,3375,3382,3412,3512,3631,3756,3870,3962,4044,4097,4120,4119,4125,4149,4156,4141,4124,4125,4069,3913,3781,3792,3931,4162,4470,4784,5033,5165,5112,4829,4360,3854,3392,3053,2796,2561,2331,2182,2138};
int e2[] = {2197,2270,2314,2364,2469,2610,2734,2842,2938,3005,3024,2994,2945,2901,2847,2771,2715,2677,2671,2706,2727,2740,2753,2781,2829,2876,2896,2897,2929,2971,3026,3113,3221,3317,3393,3436,3488,3518,3524,3550,3609,3660,3658,3634,3645,3662,3718,3819,3821,3862,3896,3899,3891,3878,3849,3789,3710,3691,3827,4097,4394,4633,4774,4773,4607,4310,3982,3674,3423,3259,3168,3092,3024,2951,2853,2750,2639,2525,2456,2412,2368,2337,2336,2346,2378,2389,2385,2358,2347,2330,2333,2341,2332,2317,2308};
int e3[] = {2333,2398,2510,2623,2704,2763,2822,2889,2955,3030,3101,3158,3189,3202,3213,3232,3263,3307,3382,3447,3499,3562,3632,3732,3853,3975,4055,4109,4122,4093,4061,3966,3808,3684,3683,3811,4011,4281,4563,4763,4817,4707,4474,4138,3794,3522,3324,3207,3117,3000,2855,2732,2626,2512,2404,2311,2271};
int e4[] = {2279,2354,2478,2605,2687,2719,2715,2693,2665,2635,2630,2626,2629,2658,2687,2701,2721,2754,2769,2781,2804,2857,2926,2993,3059,3130,3196,3251,3280,3289,3303,3315,3314,3303,3313,3329,3342,3370,3408,3442,3461,3481,3529,3591,3639,3657,3633,3611,3577,3491,3435,3435,3458,3508,3609,3779,3983,4194,4337,4362,4262,4073,3802,3494,3170,2900,2696,2590,2563,2562,2602,2652,2663,2641,2584,2517,2482,2463,2448,2444,2402,2307,2213,2158,2150};
int e5[] = {2184,2222,2264,2306,2339,2362,2385,2412,2436,2491,2563,2618,2638,2645,2676,2697,2716,2744,2788,2831,2860,2863,2874,2898,2926,2964,3030,3056,3057,3071,3091,3114,3138,3107,3041,2968,2920,2880,2875,2899,2914,2913,2914,2921,2945,2991,3077,3216,3413,3565,3587,3493,3355,3200,3086,3000,2934,2879,2846,2822,2761,2621,2462,2309,2177,2079,2046};
int e6[] = {2085,2160,2233,2299,2371,2444,2500,2525,2526,2528,2554,2595,2644,2702,2776,2845,2904,2931,2948,2952,2942,2935,2961,3016,3091,3171,3250,3323,3382,3395,3377,3380,3419,3511,3592,3629,3658,3672,3674,3650,3616,3569,3511,3466,3429,3362,3304,3262,3261,3314,3420,3622,3842,4028,4095,4000,3899,3842,3813,3726,3531,3264,2977,2714,2498,2353,2270,2253,2293,2418,2627,2842,2970,3045,3025,2906,2749,2595,2466,2387,2380,2418,2478,2537,2578,2576,2518,2451,2416,2416};
int e7[] = {2424,2445,2519,2622,2754,2868,2915,2893,2891,2919,2969,3035,3115,3203,3297,3397,3487,3540,3555,3563,3587,3623,3666,3733,3810,3866,3912,3940,3938,3933,3949,3980,4046,4129,4168,4149,4085,4035,4065,4171,4324,4467,4570,4591,4459,4208,3891,3563,3247,2960,2746,2714,2651,2546,2426,2324,2257,2251,2309,2392,2478,2526,2513,2469,2408,2358,2311,2267,2256};
int e8[] = {2294,2383,2476,2570,2646,2706,2750,2772,2791,2828,2857,2893,2955,3022,3068,3112,3159,3228,3317,3413,3500,3563,3602,3640,3691,3739,3787,3850,3913,3968,4033,4072,4073,4001,3840,3683,3597,3614,3712,3894,4134,4353,4485,4458,4293,4015,3746,3538,3403,3333,3284,3202,3119,3037,2953,2870,2798,2719,2646,2575,2490,2393,2277,2158,2076,2047,2050};
int e9[] = {2074,2122,2177,2217,2235,2265,2307,2360,2424,2505,2601,2707,2820,2915,3006,3096,3209,3336,3424,3462,3485,3506,3521,3555,3605,3662,3722,3772,3816,3874,3949,4011,4045,4029,3982,3896,3766,3616,3580,3632,3721,3844,4035,4245,4449,4561,4529,4349,4049,3654,3266,2952,2740,2637,2615,2643,2673,2699,2720,2743,2768,2804,2843,2869,2871,2868,2855,2828,2818,2833,2862,2886,2887,2877,2866,2869,2889,2892,2895,2890,2877,2872,2855};
int e10[] = {2861,2922,3003,3088,3175,3243,3310,3385,3447,3521,3581,3641,3736,3829,3897,3973,4048,4086,4096,4099,4070,4027,4001,3983,3930,3860,3842,4001,4288,4579,4761,4760,4568,4300,4051,3893,3745,3536,3267,3016,2859,2787,2770,2731,2663,2569,2452,2326,2219,2136,2060,1997,1951,1921,1930};
int e11[] = {1950,1967,1991,2050,2141,2236,2351,2483,2585,2659,2701,2728,2764,2820,2949,3114,3269,3430,3554,3622,3626,3607,3604,3611,3598,3590,3610,3650,3682,3696,3704,3727,3756,3807,3853,3891,3916,3933,3934,3863,3762,3679,3661,3681,3692,3742,3919,4175,4396,4469,4380,4110,3707,3256,2882,2596,2494,2539,2625,2694,2737,2749,2757,2774,2809,2840,2838,2789,2715,2627,2543,2477,2420,2375,2365};
int e12[] = {2387,2436,2517,2609,2710,2784,2819,2844,2890,2962,3044,3102,3154,3187,3219,3263,3296,3321,3350,3385,3463,3545,3565,3612,3657,3669,3666,3627,3568,3501,3447,3413,3409,3436,3455,3424,3350,3270,3227,3296,3530,3817,4094,4310,4388,4298,4078,3791,3484,3213,2997,2884,2856,2908,2986,3049,3045,2976,2836,2662,2508,2382,2262,2135,2014,1911,1847,1819,1837};
int e13[] = {1912,1999,2059,2112,2176,2253,2350,2450,2537,2623,2703,2764,2837,2921,3018,3110,3182,3224,3216,3163,3119,3077,3044,3035,3060,3114,3213,3324,3426,3496,3547,3574,3577,3564,3535,3488,3364,3191,3091,3154,3271,3423,3539,3733,3949,4129,4204,4162,3996,3763,3537,3360,3265,3246,3244,3226,3161,3074,2985,2885,2803,2734,2684,2672,2672,2687,2697,2679,2637,2580,2531,2497,2503};



int main(int argc, char **argv){
	printf("algus\n");
	//setup better access to data
	int *list[13];
	int lens[13];
	list[0] = e1; lens[0] = sizeof(e1) / sizeof(int);
	list[1] = e2; lens[1] = sizeof(e2) / sizeof(int);
	list[2] = e3; lens[2] = sizeof(e3) / sizeof(int);
	list[3] = e4; lens[3] = sizeof(e4) / sizeof(int);
	list[4] = e5; lens[4] = sizeof(e5) / sizeof(int);
	list[5] = e6; lens[5] = sizeof(e6) / sizeof(int);
	list[6] = e7; lens[6] = sizeof(e7) / sizeof(int);
	list[7] = e8; lens[7] = sizeof(e8) / sizeof(int);
	list[8] = e9; lens[8] = sizeof(e9) / sizeof(int);
	list[9] = e10; lens[9] = sizeof(e10) / sizeof(int);
	list[10] = e11; lens[10] = sizeof(e11) / sizeof(int);
	list[11] = e12; lens[11] = sizeof(e12) / sizeof(int);
	list[12] = e13; lens[12] = sizeof(e13) / sizeof(int);
	
	printf("peale sizeof'i kasutamist\n");
	
	//prepare the file   
	time_t now = time(NULL);
	struct tm * timeinfo = localtime (&now);
	char halfname2[20];
	sprintf(halfname2, "%s", asctime(timeinfo));
	char *halfname = strchr(halfname2, ' ')+1;
	char *b = strchr(halfname, ':');
	if(b != NULL)b[0] = '.';
	b = strchr(b, ':');
	if(b != NULL)b[0]=0;
		
	
	char filename[100];

	
	printf("enne faili avamist\n");
	sprintf(filename, "./vorst %s.json",halfname); 
	FILE *f = fopen(filename, "w");
	if (f == NULL){
		printf("cannot create output file %s\n",filename);
		return 1;      
	}

	printf("peale faili avamist\n");
	//write meta rows
	int i, j;
	double period = 1 / signal_frequency;
	for(i = 0; i < number_of_channels; i++){
		// example: {"type":"meta", "channel":"acc_x", "interval":0.01, "unit":"m/s2" }
		fprintf(f, "{\"type\":\"meta\",\"channel\":\"channel-%d\",\"interval\":%.3f, \"unit\":\"m/s2\"}\n", i+1, period);
	}
	printf("peale esimest fprintf'i\n");

	//start main loop - generate an exercise, sleep, generate, sleep
	int packet_id = 1;
	int other_counter = 0;
	while(1){
		/*example
		{"type":"regular", "row_id":1, "channels":{	
			"acc_x":[26,26,26,22,26,21, 26,20,26, 26], 
			"acc_y":[33,33,33,33,33,33],
			"acc_z":[44,44,44,44,44,44]
			}
		}*/
		fprintf(f, "{\"type\":\"regular\", \"row_id\":%d, \"channels\":{\n", packet_id);
		for(i = 0; i < number_of_channels; i++){
			fprintf(f, "\t\"channel-%d\":[", i+1);
			if(i == 0){
				//meaningful events in one channel only
				int len = lens[other_counter % 13];
				for(j = 0; j < len; j++ ){
					if(j != len -1) fprintf(f, "%d,",list[other_counter % 13][j]);
					else fprintf(f, "%d",list[other_counter % 13][j]);
				}
			}
			
			else if(i == 1){
				//something here as well
				for(j = 0; j < 200; j++ ){
					if(j != 200 - 1) fprintf(f, "%d,",j%5==0?-1000:1000);
					else fprintf(f, "%d",j%5==0?-1000:1000);
				}
			}
			
			else {
				//constant here
				for(j = 0; j < 200; j++ ){
					if(j != 200 - 1) fprintf(f, "%d,", 500 + 400 * i);
					else fprintf(f, "%d", 500 + 400 * i);
				}				
			}
			
			if(i != number_of_channels - 1)fprintf(f,"],\n");
			else fprintf(f,"]\n");
		}
		fprintf(f,"\t}\n}\n");
		other_counter++;
		packet_id++;
		printf("%d data objects created\n",other_counter);
		
		if(other_counter % how_often_max == 0 ){
			/*example
			{"type":"avg", "row_id":1, "channels":{	
				"acc_x":[26,26,26,22,26,21, 26,20,26, 26], 
				"acc_y":[33,33,33,33,33,33],
				"acc_z":[44,44,44,44,44,44]
				}
			}*/					//determine the maximum length of the given exercises
			int maxlen = 0;
			int a;
			for(a = other_counter - 1; a > other_counter - 1 - how_often_max ; a--)if(lens[a % 13] > maxlen) maxlen = lens[a % 13];
						
			fprintf(f, "{\"type\":\"avg\", \"row_id\":%d, \"channels\":{\n", packet_id);
			for(i = 0; i < number_of_channels; i++){
				fprintf(f, "\t\"channel-%d\":[", i+1);
				if(i == 0){
					for(j = 0; j < maxlen; j++ ){//loop over slots of samples
						int avgval = 0;
						int cnt = 0;
						
						for(a = other_counter - 1; a > other_counter - 1 - how_often_max ; a--){//loop over last exercises
							
							if(j <= lens[a % 13] - 1){
								avgval += list[a % 13][j];
								cnt++;
							}						
						}
						
						if(cnt != 0)avgval = avgval / cnt;
						if(j != maxlen - 1) fprintf(f, "%d,", avgval);
						else fprintf(f, "%d", avgval);
					}
				}
				else if(i == 1){
					//something here as well
					for(j = 0; j < 200; j++ ){
						if(j != 200 - 1) fprintf(f, "%d,",j%5==0?-1000:1000);
						else fprintf(f, "%d",j%5==0?-1000:1000);
					}
				}
				
				else {
					//constant here
					for(j = 0; j < 200; j++ ){
						if(j != 200 - 1) fprintf(f, "%d,", 500 + 400 * i);
						else fprintf(f, "%d", 500 + 400 * i);
					}				
				}
				if(i != number_of_channels - 1)fprintf(f,"],\n");
				else fprintf(f,"]\n");
			}
			fprintf(f,"\t}\n}\n");
			packet_id++;		


			fprintf(f, "{\"type\":\"min\", \"row_id\":%d, \"channels\":{\n", packet_id);
			for(i = 0; i < number_of_channels; i++){
				fprintf(f, "\t\"channel-%d\":[", i+1);
				if(i == 0){
					for(j = 0; j < maxlen; j++ ){//loop over slots of samples
						int min = 33000;
												
						for(a = other_counter - 1; a > other_counter - 1 - how_often_max ; a--){//loop over last exercises
							if(j <= lens[a % 13] - 1) if(min > list[a % 13][j]) min = list[a % 13][j];
						}
						
						
						if(j != maxlen - 1) fprintf(f, "%d,", min-100);
						else fprintf(f, "%d", min-100);
					}
				}
				else{
					for(j = 0; j < 200; j++ ){
						if(j != 200 - 1) fprintf(f, "%d,",-1110);
						else fprintf(f, "%d",-1110);
					}
				}
				
				if(i != number_of_channels - 1)fprintf(f,"],\n");
				else fprintf(f,"]\n");
			}
			fprintf(f,"\t}\n}\n");
			packet_id++;	

			fprintf(f, "{\"type\":\"max\", \"row_id\":%d, \"channels\":{\n", packet_id);
			for(i = 0; i < number_of_channels; i++){
				fprintf(f, "\t\"channel-%d\":[", i+1);
				if(i == 0){
					for(j = 0; j < maxlen; j++ ){//loop over slots of samples
						int max = -33000;
												
						for(a = other_counter - 1; a > other_counter - 1 - how_often_max ; a--){//loop over last exercises
							if(j <= lens[a % 13] - 1) if(max < list[a % 13][j]) max = list[a % 13][j];
						}
						
						
						if(j != maxlen - 1) fprintf(f, "%d,", max+100);
						else fprintf(f, "%d", max+100);
					}
				}
				else{
					for(j = 0; j < 200; j++ ){
						if(j != 200 - 1) fprintf(f, "%d,",2110);
						else fprintf(f, "%d",2110);
					}
				}
				
				if(i != number_of_channels - 1)fprintf(f,"],\n");
				else fprintf(f,"]\n");
			}
			fprintf(f,"\t}\n}\n");
			packet_id++;	
			
		}
		
		
		//sleep(interval_between_exercises); //this works in windows
		usleep(interval_between_exercises * 1000); // for linux
	}
	
	return 0;
}
